﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Wubi.Utils
{
    public static class FloatExtentsions
    {
        public static float ClampAngle(this float value, float min = float.MinValue, float max = float.MaxValue)
        {
            if (value < -360)
                value += 360;
            if (value > 360)
                value -= 360;
            return Mathf.Clamp(value, min, max);
        }
    }

    public static class EnumerableExtensions
    {
        public static void Foreach<T>(this IEnumerable<T> enumerable, System.Action<T> action)
        {
            foreach(var el in enumerable)
            {
                if (action != null) action(el);
            }
        }
        public static void Foreach<T>(this IEnumerable<T> enumerable, System.Action<T, int> action)
        {
            int i = 0;
            foreach (var el in enumerable)
            {
                if (action != null) action(el, i++);
            }
        }
        public static string Print<T>(this IEnumerable<T> enumerable, string delimiter = ", ", System.Func<T, string> formatter = null)
        {
            return string.Join(delimiter, enumerable.Select(e => formatter == null ? e.ToString() : formatter(e)).ToArray());
        }
    }

    public static class VectorExtensions
    {
        public static Vector3 ToVector3(this Vector2 v2, float z = 0)
        {
            return new Vector3(v2.x, v2.y, z);
        }
        public static bool IsNegativeInf(this Vector3 v3)
        {
            return float.IsNegativeInfinity(v3.x) || float.IsNegativeInfinity(v3.y) || float.IsNegativeInfinity(v3.z);
        }
        public static bool IsPositiveInf(this Vector3 v3)
        {
            return float.IsPositiveInfinity(v3.x) || float.IsPositiveInfinity(v3.y) || float.IsPositiveInfinity(v3.z);
        }
        public static bool IsNegativeInf(this Vector2 v2)
        {
            return float.IsNegativeInfinity(v2.x) || float.IsNegativeInfinity(v2.y);
        }
        public static bool IsPositiveInf(this Vector2 v2)
        {
            return float.IsPositiveInfinity(v2.x) || float.IsPositiveInfinity(v2.y);
        }
    }

    public static class TransformExtensions
    {
        public static void SetLayer(this Transform t, int layer, bool isRecursively = true)
        {
            t.gameObject.layer = layer;
            if (!isRecursively) return;
            foreach(Transform child in t)
            {
                child.SetLayer(layer, isRecursively);
            }
        }
    }
}

public static class UIHelper
{
    public static Vector2 WorldToUIPos(Vector3 worldPos, RectTransform rectTransform)
    {
        var vpStackTop = Camera.main.WorldToViewportPoint(worldPos) - Vector3.one * .5f;
        var uiSize = rectTransform.rect.size;
        return new Vector2(vpStackTop.x * uiSize.x, vpStackTop.y * uiSize.y);
    }
}